<!--
 * @页面名称:树功能单页面操作
 * @描述: 
 * @作者: 
 * @Date:
-->
<template>
  <div style="margin-top: 10px; height: 100%">
    <!-- 卡片容器 -->
    <el-card shadow="hover" class="elCard" v-loading="loading" :element-loading-text="text" style="height: 100%">
      <template #header>
        <!-- 头部flex布局 -->
        <el-row type="flex" align="middle" justify="center">
          <el-col :span="12">
            <!-- 左上方文字名称 -->
            <span v-if="type == 0">源服务器:{{ databaseName }}</span>
            <span v-else>目标服务器:{{ databaseName }}</span>
          </el-col>
          <el-col :span="12">
            <!-- 右侧操作按钮 -->
            <el-button-group class="ebgbtn">
              <el-button type="primary" icon="Delete" size="small" :disabled="deldis || isActive" @click="deleteNode"
                >删除节点</el-button
              >
              <el-button type="primary" icon="Reading" size="small" :disabled="isActive" @click="viewProfile">
                查看全宗</el-button
              >
              <el-button type="primary" icon="Connection" size="small" :disabled="isActive" @click="dialogVisible = true"
                >数据库连接</el-button
              >
            </el-button-group>
          </el-col>
        </el-row>
      </template>
      <!-- ztree树组件调用 -->
      <ztree
        style="height: calc(100% - 52px); padding: 5px 8px"
        :setting="treeSetting.setting"
        :nodes="treeSetting.treeData"
        @onClick="onClick"
        @onCreated="handleCreated"
        @onAsyncSuccess="onAsyncSuccess"
      >
      </ztree>
    </el-card>
    <!-- 服务器连接弹框 -->
    <el-dialog v-model="dialogVisible" title="数据库连接" width="30%">
      <el-form label-width="100px" :model="formData" ref="formRef" :rules="rules">
        <!--服务器地址框  -->
        <el-form-item label="服务器地址" prop="serverAddress">
          <el-input v-model="formData.serverAddress" placeholder="请输入服务器地址"></el-input>
        </el-form-item>
        <!-- 用户名框 -->
        <el-form-item label="用户名" prop="userName">
          <el-input v-model="formData.userName" placeholder="请输入用户名"></el-input>
        </el-form-item>
        <!-- 密码框 -->
        <el-form-item label="密码" prop="password">
          <el-input v-model="formData.password" show-password placeholder="请输入密码"></el-input>
        </el-form-item>
        <!-- 数据库类型下拉框 -->
        <el-form-item label="数据库类型" prop="databaseType">
          <el-select v-model="formData.databaseType" placeholder="请选择数据库类型">
            <div v-for="(item, index) in dbTypeOpts" :key="index">
              <el-option :label="item.label" :value="item.value"></el-option>
            </div>
          </el-select>
        </el-form-item>
        <!-- 数据库下拉框 -->
        <el-form-item label="数据库" prop="database">
          <el-select v-model="formData.database" @visible-change="visibleChange($event)" placeholder="请选择数据库">
            <div v-for="(item, index) in dbOptions" :key="index">
              <el-option :label="item" :value="item"></el-option>
            </div>
          </el-select>
        </el-form-item>
        <!-- 数据库连接表单操作按钮 -->
        <el-form-item>
          <el-button class="rowBtn" type="primary" @click="submitConnect">连接</el-button>
          <el-button class="rowBtn" @click="saveConnect" type="primary" :disabled="savedis">保存</el-button>
          <el-button class="rowBtn" type="primary" @click="editConnect">关闭</el-button>
        </el-form-item>
      </el-form>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, nextTick, watch } from "vue";
import type { FormInstance, FormRules } from "element-plus";
import Ztree from "@/components/Ztree/Ztree.vue";
//获取子节点的表单
import asyncData from "./getAsyncNode";
import useCurrentInstance from "@/utils/useCurrentInstance";

const props = defineProps({
  type: {
    type: Number,
    default: 0
  }
});
const emit = defineEmits(["getZtreeObj"]);

const { proxy } = useCurrentInstance();

const loading = ref(false); //加载标识
const text = ref(""); //加载字体
const databaseName = ref(""); //服务器地址
const savedis = ref(true); //保存按钮
const deldis = ref(true); //删除节点按钮
const isActive = ref(false); //加载状态
const dialogVisible = ref(false); //弹出框状态
const formRef = ref<FormInstance>(); // 定义表单实例
const formData = ref({
  serverAddress: "", //数据库地址
  userName: "", //用户名
  password: "", //密码
  databaseType: 0, //数据库类型
  database: 0, //数据库
  type: props.type //源数据 0 目标数据 1
}); //数据库提交表单
const dbTypeOpts = ref([
  { label: "SqlServer", value: 0 },
  { label: "MySql", value: 1 },
  { label: "Oracle", value: 2 },
  { label: "Dm", value: 3 },
  { label: "HighGo", value: 4 },
  { label: "KingBase", value: 5 },
  { label: "SQL2019", value: 6 }
]); //数据库类型数据
const dbOptions: any = ref([]); //数据库名称数据
const rules = ref<FormRules>({
  //服务器地址
  serverAddress: [{ required: true, message: "请输入服务器地址", trigger: "blur" }],
  userName: [{ required: true, message: "请输入用户名", trigger: "blur" }],
  password: [{ required: true, message: "请输入密码", trigger: "blur" }],
  databaseType: [{ required: true, message: "请选择数据库类型", trigger: "change" }],
  database: [{ required: true, message: "请选择数据库", trigger: "change" }]
});
const filter = () => {};
// tree配置
const treeSetting = reactive({
  setting: {
    // ztree配置
    data: {
      simpleData: {
        enable: true,
        idKey: "ID",
        pIdKey: "Father_ID"
      },
      key: {
        name: "Name"
      }
    },
    async: {
      //异步加载子节点
      enable: true,
      url: "",
      type: "get",
      autoParam: [],
      contentType: "application/json",
      dataFilter: filter
    },
    view: {
      showIcon: false
    }
  },
  treeData: [] as any[],
  ztreeObj: {} as any,
  ztreeAllObj: {} as any
});
// 注册signal服务
const signalrEvent = () => {
  // 注册signal服务(用于复制节点)
  proxy.signalr.off("SendFCDeleteNode");
  proxy.signalr.on("SendFCDeleteNode", (res: any) => {
    proxy.$showLoading({ tip: res });
    if (res.trim().startsWith("start")) {
      // 传输开始
      proxy.$showLoading({ tip: res });
    }
    if (res.trim().startsWith("stop")) {
      // 传输结束
      proxy.$hideLoading();
    }
  });
};
//获取所有数据库名称
const visibleChange = (flag?: boolean) => {
  //判断下拉框状态 true开启 false关闭
  if (flag) {
    //调用获取数据库名称api
    proxy.$vueAxios.get("FondsCopy/GetLibraryNameByDatabase", { ...formData.value }).then((res: any) => {
      if (!res.Mark && res.Mark !== undefined) {
        proxy.$message.error(res.Msg);
      } else {
        dbOptions.value = res;
      }
    });
  }
};
// 点击树节点
const onClick = (treeNode: any) => {
  treeSetting.ztreeObj = treeNode;
};
// 初始化树
const handleCreated = (ztreeObj?: any) => {
  emit("getZtreeObj", ztreeObj);
  treeSetting.ztreeAllObj = ztreeObj;
};
// 数据库连接
const submitConnect = () => {
  deldis.value = true;
  formRef.value!.validate((isValid: boolean) => {
    if (isValid) {
      proxy.$vueAxios.post("FondsCopy/ValidateDatabase", { ...formData.value }).then((res: any) => {
        //左上角名称数据
        databaseName.value = `${formData.value.serverAddress}\\${formData.value.database}`;
        //将tree数组置空
        treeSetting.treeData = [];
        if (res.Mark) {
          proxy.$message({
            type: "success",
            message: "连接成功"
          });
          savedis.value = false;
        } else {
          proxy.$message.error("连接失败");
        }
      });
    }
  });
};
// 保存
const saveConnect = () => {
  formRef.value!.validate((isValid: boolean) => {
    if (isValid) {
      proxy.$vueAxios.post("FondsCopy/AddDatabaseInfo", { ...formData.value }).then((res: any) => {
        if (res.Mark) {
          proxy.$message({
            type: "success",
            message: "保存成功"
          });
          savedis.value = false;
        } else {
          proxy.$message.error("保存失败");
        }
      });
    }
  });
};
// 关闭
const editConnect = () => {
  dialogVisible.value = false;
  //清空表单校验
  nextTick(() => {
    formRef.value!.resetFields();
  });
};
//获取保存的数据库连接
const getSaveConnect = () => {
  proxy.$vueAxios.get("FondsCopy/GetDatabaseInfo", { type: formData.value.type }).then((res: any) => {
    if (res.Mark) {
      //获取保存的数据
      const list = res.List[0];
      //将数据存入form
      formData.value = {
        serverAddress: list.ServerAddress,
        userName: list.UserName,
        password: list.Password,
        databaseType: list.DatabaseType,
        database: list.Database,
        type: list.Type
      };
      proxy.$vueAxios.post("FondsCopy/ValidateDatabase", { ...formData.value }).then((res: any) => {
        //成功后更改左上角名称
        if (res.Mark) {
          databaseName.value = `${list.ServerAddress}\\${list.Database}`;
        }
      });
    }
  });
};
// 仅查看全宗
const viewProfile = () => {
  //遮罩层打开
  loading.value = true;
  text.value = "正在加载数据....";
  //获取全部树数据
  proxy.$vueAxios.get("FondsCopy/OnlyLoadFonds", { type: formData.value.type }, { noLoading: true }).then((res: any) => {
    if (res.Mark) {
      //树的数据赋值
      res.List.forEach((item: any) => {
        item.isParent = item.IsFather;
      });
      treeSetting.treeData = res.List;
      deldis.value = false;
      proxy.$message({
        type: "success",
        message: "加载成功"
      });
    } else {
      proxy.$message.error("全宗查看失败");
    }
    // 遮罩层关闭
    loading.value = false;
  });
};
// 删除节点
const deleteNode = () => {
  // 如果选中不为空
  if (Object.keys(treeSetting.ztreeObj).length > 0) {
    //调用删除
    proxy
      .$confirm(`当前节点为[${getFilePath(treeSetting.ztreeObj)}],是否删除?`, "删除节点", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        closeOnClickModal: false,
        type: "warning"
      })
      .then(() => {
        //判断是否为数据库数据
        if (treeSetting.ztreeObj.IsdbData) {
          //调用删除api
          proxy.$vueAxios
            .post(
              "FondsCopy/DeleteNode",
              {
                id: treeSetting.ztreeObj.ID,
                fonds_ID: treeSetting.ztreeObj.Fonds_ID,
                nodeType: treeSetting.ztreeObj.Type,
                type: props.type,
                clientUser: proxy.signalr.connectionId
              },
              { noLoading: true }
            )
            .then((res: any) => {
              // 如果删除成功删除节点
              if (res.Mark) {
                treeSetting.ztreeAllObj.removeNode(treeSetting.ztreeObj);
              }
            });
        } else if (treeSetting.ztreeObj.children === undefined) {
          //如果没有子级则删除当前节点
          treeSetting.ztreeAllObj.removeNode(treeSetting.ztreeObj);
        } else {
          //遍历子节点
          const ids: any[] = [];
          treeSetting.ztreeObj.children.forEach((item: { ID: any }, index: any) => {
            ids.push(item.ID);
          });
          const params = {
            idList: ids,
            fonds_ID: treeSetting.ztreeObj.Fonds_ID,
            nodeType: treeSetting.ztreeObj.Type,
            type: props.type,
            clientUser: proxy.signalr.connectionId
          };
          proxy.$vueAxios.post("FondsCopy/DeleteNodeList", params, { noLoading: true }).then((res: any) => {
            if (res.Mark) {
              proxy.$message({
                type: "success",
                message: "删除成功"
              });
              treeSetting.ztreeAllObj.removeNode(treeSetting.ztreeObj);
            } else {
              proxy.$message.error("删除失败");
            }
          });
        }
      });
  } else {
    proxy.$message.error(`请选中要删除的节点`);
  }
};
// 获取当前节点的所有父级节点
const getFilePath = (treeObj: any) => {
  //如果对象为空,返回空
  if (treeObj == null) return "";
  let filename = treeObj.Name;
  //获取父级节点
  let pNode = treeObj.getParentNode();
  //如果父节点不为空
  if (pNode != null) {
    //递归调用
    filename = `${getFilePath(pNode)}>${filename}`;
  }
  return filename;
};
// 异步加载子节点
const onAsyncSuccess = (treeNode: any) => {
  switch (treeNode.Type) {
    case 1:
      loading.value = true;
      asyncData.asyncData1(formData.value.type, treeNode.Fonds_ID).then((res: any) => {
        res.data.List.forEach((item: any) => {
          item.isParent = item.IsFather;
        });
        if (res.data.List != null && res.data.List.length > 0) {
          if (treeNode === undefined) {
            treeSetting.ztreeAllObj.addNodes(null, res.data.List, true); // 如果是根节点，那么就在null后面加载数据
          } else {
            treeSetting.ztreeAllObj.addNodes(treeNode, res.data.List, true); //如果是加载子节点，那么就是父节点下面加载
          }
          treeSetting.ztreeAllObj.expandNode(treeNode, true, false, false); // 将新获取的子节点展开
        }
        loading.value = false;
      });
      break;
    case 2:
      loading.value = true;
      asyncData.asyncData2(formData.value.type, treeNode.Fonds_ID, treeNode.ID).then(res => {
        res.data.List.forEach((item: any) => {
          item.isParent = item.IsFather;
        });
        if (res.data.List != null && res.data.List.length > 0) {
          if (treeNode === undefined) {
            treeSetting.ztreeAllObj.addNodes(null, res.data.List, true); // 如果是根节点，那么就在null后面加载数据
          } else {
            treeSetting.ztreeAllObj.addNodes(treeNode, res.data.List, true); //如果是加载子节点，那么就是父节点下面加载
          }
          treeSetting.ztreeAllObj.expandNode(treeNode, true, false, false); // 将新获取的子节点展开
        }
        loading.value = false;
      });
      break;
    case 3:
      loading.value = true;
      asyncData.asyncData3(formData.value.type, treeNode.ID).then(res => {
        res.data.List.forEach((item: any) => {
          item.isParent = item.IsFather;
        });
        if (res.data.List != null && res.data.List.length > 0) {
          if (treeNode === undefined) {
            treeSetting.ztreeAllObj.addNodes(null, res.data.List, true); // 如果是根节点，那么就在null后面加载数据
          } else {
            treeSetting.ztreeAllObj.addNodes(treeNode, res.data.List, true); //如果是加载子节点，那么就是父节点下面加载
          }
          treeSetting.ztreeAllObj.expandNode(treeNode, true, false, false); // 将新获取的子节点展开
        }
        loading.value = false;
      });
      break;
    case 4:
      loading.value = true;
      asyncData.asyncData4(formData.value.type, treeNode.UpOneLevel_ID, treeNode.ID, treeNode.WD_Key).then(res => {
        res.data.List.forEach((item: any) => {
          item.isParent = item.IsFather;
        });
        if (res.data.List != null && res.data.List.length > 0) {
          if (treeNode === undefined) {
            treeSetting.ztreeAllObj.addNodes(null, res.data.List, true); // 如果是根节点，那么就在null后面加载数据
          } else {
            treeSetting.ztreeAllObj.addNodes(treeNode, res.data.List, true); //如果是加载子节点，那么就是父节点下面加载
          }
          treeSetting.ztreeAllObj.expandNode(treeNode, true, false, false); // 将新获取的子节点展开
        }
        loading.value = false;
      });
      break;
    case 5:
      loading.value = true;
      asyncData.asyncData5(formData.value.type, treeNode.ID, treeNode.Table_Name).then(res => {
        res.data.List.forEach((item: any) => {
          item.isParent = item.IsFather;
        });
        if (res.data.List != null && res.data.List.length > 0) {
          if (treeNode === undefined) {
            treeSetting.ztreeAllObj.addNodes(null, res.data.List, true); // 如果是根节点，那么就在null后面加载数据
          } else {
            treeSetting.ztreeAllObj.addNodes(treeNode, res.data.List, true); //如果是加载子节点，那么就是父节点下面加载
          }
          treeSetting.ztreeAllObj.expandNode(treeNode, true, false, false); // 将新获取的子节点展开
        }
        loading.value = false;
      });
      break;
    case 6:
      loading.value = true;
      asyncData
        .asyncDataMore(formData.value.type, treeNode.UpOneLevel_ID, treeNode.Table_Name, treeNode.Type, treeNode.ID)
        .then(res => {
          res.data.List.forEach((item: any) => {
            item.isParent = item.IsFather;
          });
          if (res.data.List != null && res.data.List.length > 0) {
            if (treeNode === undefined) {
              treeSetting.ztreeAllObj.addNodes(null, res.data.List, true); // 如果是根节点，那么就在null后面加载数据
            } else {
              treeSetting.ztreeAllObj.addNodes(treeNode, res.data.List, true); //如果是加载子节点，那么就是父节点下面加载
            }
            treeSetting.ztreeAllObj.expandNode(treeNode, true, false, false); // 将新获取的子节点展开
          }
          loading.value = false;
        });
      break;
    case 7:
      loading.value = true;
      asyncData
        .asyncDataMore(formData.value.type, treeNode.UpOneLevel_ID, treeNode.Table_Name, treeNode.Type, treeNode.ID)
        .then(res => {
          res.data.List.forEach((item: any) => {
            item.isParent = item.IsFather;
          });
          if (res.data.List != null && res.data.List.length > 0) {
            if (treeNode === undefined) {
              treeSetting.ztreeAllObj.addNodes(null, res.data.List, true); // 如果是根节点，那么就在null后面加载数据
            } else {
              treeSetting.ztreeAllObj.addNodes(treeNode, res.data.List, true); //如果是加载子节点，那么就是父节点下面加载
            }
            treeSetting.ztreeAllObj.expandNode(treeNode, true, false, false); // 将新获取的子节点展开
          }
          loading.value = false;
        });
      break;
    case 8:
      loading.value = true;
      asyncData
        .asyncDataMore(formData.value.type, treeNode.UpOneLevel_ID, treeNode.Table_Name, treeNode.Type, treeNode.ID)
        .then(res => {
          res.data.List.forEach((item: any) => {
            item.isParent = item.IsFather;
          });
          if (res.data.List != null && res.data.List.length > 0) {
            if (treeNode === undefined) {
              treeSetting.ztreeAllObj.addNodes(null, res.data.List, true); // 如果是根节点，那么就在null后面加载数据
            } else {
              treeSetting.ztreeAllObj.addNodes(treeNode, res.data.List, true); //如果是加载子节点，那么就是父节点下面加载
            }
            treeSetting.ztreeAllObj.expandNode(treeNode, true, false, false); // 将新获取的子节点展开
          }
          loading.value = false;
        });
      break;
    case 9:
      loading.value = true;
      asyncData
        .asyncDataMore(formData.value.type, treeNode.UpOneLevel_ID, treeNode.Table_Name, treeNode.Type, treeNode.ID)
        .then(res => {
          res.data.List.forEach((item: any) => {
            item.isParent = item.IsFather;
          });
          if (res.data.List != null && res.data.List.length > 0) {
            if (treeNode === undefined) {
              treeSetting.ztreeAllObj.addNodes(null, res.data.List, true); // 如果是根节点，那么就在null后面加载数据
            } else {
              treeSetting.ztreeAllObj.addNodes(treeNode, res.data.List, true); //如果是加载子节点，那么就是父节点下面加载
            }
            treeSetting.ztreeAllObj.expandNode(treeNode, true, false, false); // 将新获取的子节点展开
          }
          loading.value = false;
        });
      break;
    case 10:
      loading.value = true;
      asyncData.asyncData10(formData.value.type, treeNode.UpOneLevel_ID, treeNode.Father_ID).then(res => {
        res.data.List.forEach((item: any) => {
          item.isParent = item.IsFather;
        });
        if (res.data.List != null && res.data.List.length > 0) {
          if (treeNode === undefined) {
            treeSetting.ztreeAllObj.addNodes(null, res.data.List, true); // 如果是根节点，那么就在null后面加载数据
          } else {
            treeSetting.ztreeAllObj.addNodes(treeNode, res.data.List, true); //如果是加载子节点，那么就是父节点下面加载
          }
          treeSetting.ztreeAllObj.expandNode(treeNode, true, false, false); // 将新获取的子节点展开
        }
        loading.value = false;
      });
      break;
    case 11:
      loading.value = true;
      asyncData
        .asyncDataMore(formData.value.type, treeNode.UpOneLevel_ID, treeNode.Table_Name, treeNode.Type, treeNode.ID)
        .then(res => {
          res.data.List.forEach((item: any) => {
            item.isParent = item.IsFather;
          });
          if (res.data.List != null && res.data.List.length > 0) {
            if (treeNode === undefined) {
              treeSetting.ztreeAllObj.addNodes(null, res.data.List, true); // 如果是根节点，那么就在null后面加载数据
            } else {
              treeSetting.ztreeAllObj.addNodes(treeNode, res.data.List, true); //如果是加载子节点，那么就是父节点下面加载
            }
            treeSetting.ztreeAllObj.expandNode(treeNode, true, false, false); // 将新获取的子节点展开
          }
          loading.value = false;
        });
      break;
    case 12:
      loading.value = true;
      asyncData
        .asyncDataMore(formData.value.type, treeNode.UpOneLevel_ID, treeNode.Table_Name, treeNode.Type, treeNode.ID)
        .then(res => {
          res.data.List.forEach((item: any) => {
            item.isParent = item.IsFather;
          });
          if (res.data.List != null && res.data.List.length > 0) {
            if (treeNode === undefined) {
              treeSetting.ztreeAllObj.addNodes(null, res.data.List, true); // 如果是根节点，那么就在null后面加载数据
            } else {
              treeSetting.ztreeAllObj.addNodes(treeNode, res.data.List, true); //如果是加载子节点，那么就是父节点下面加载
            }
            treeSetting.ztreeAllObj.expandNode(treeNode, true, false, false); // 将新获取的子节点展开
          }
          loading.value = false;
        });
      break;
  }
};
watch(
  () => formData.value,
  (newValue, oldValue) => {
    newValue.database = 0;
    dbOptions.value = [];
  }
);
onMounted(() => {
  visibleChange();
  getSaveConnect();
  //默认调用,获取ztree对象
  handleCreated();
  signalrEvent();
});
defineExpose({ viewProfile });
</script>

<style scoped lang="scss">
.ebgbtn {
  float: right;
}
:deep(.el-card__body) {
  height: calc(100% - 40px);
  overflow: auto;
}
</style>
